package ncme.auto.framework.core.services.Impl.mian;

import ncme.auto.framework.core.callback.AutoProcessControllerPart;
import ncme.auto.framework.core.entities.aspect.parameter.ServiceInfo;
import ncme.auto.framework.core.exceptions.AutoException;
import ncme.auto.framework.core.exceptions.ExceptionEnum;
import ncme.auto.framework.core.services.Impl.base.BaseAutoMapperServiceImpl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class OneToOneAutoMapperImpl<E, PRIMARY_CLASS, SECONDARY_CLASS> extends BaseAutoMapperServiceImpl<E, PRIMARY_CLASS, SECONDARY_CLASS> {

    public abstract void customService(AutoProcessControllerPart autoProcessControllerPart, ServiceInfo serviceInfo) throws Throwable;

    //region######################################## get ###########################################

    public Integer getSecondaryIdFromPrimaryId(Integer primaryId) {
        List<Integer> fromId = getIdsFromId(primaryId, true);
        if (fromId.size() > 1)
            throw new AutoException(ExceptionEnum.JDBC, PRIMARY_FIELD_NAME + ":" + primaryId + "有多个映射关系");
        return fromId.size() == 1 ? fromId.get(0) : null;
    }

    public SECONDARY_CLASS getSecondaryEntityFromPrimaryId(Integer primaryId) {
        Integer secondaryId = getSecondaryIdFromPrimaryId(primaryId);
        return secondaryEntityBaseService.getEntityById(secondaryId, true);
    }

    public Integer getPrimaryIdFromSecondaryId(Integer secondaryId) {
        List<Integer> fromId = getIdsFromId(secondaryId, false);
        if (fromId.size() > 1)
            throw new AutoException(ExceptionEnum.JDBC, SECONDARY_FIELD_NAME + ":" + secondaryId + "有多个映射关系");
        return fromId.size() == 1 ? fromId.get(0) : null;
    }

    public PRIMARY_CLASS getPrimaryEntityFromSecondaryId(Integer primaryId) {
        Integer secondaryId = getPrimaryIdFromSecondaryId(primaryId);
        return primaryEntityBaseService.getEntityById(secondaryId, true);
    }

    //endregion

    //region######################################## add ###########################################

    public void addSecondaryIdForPrimaryId(Integer primaryId, Integer secondaryId) {
        if (getSecondaryIdFromPrimaryId(primaryId) != null)  //primary是否已存在映射
            throw new AutoException(ExceptionEnum.JDBC, PRIMARY_FIELD_NAME + ":" + primaryId + "已存在映射");
        if (getPrimaryIdFromSecondaryId(secondaryId) != null)  //secondary是否已存在映射
            throw new AutoException(ExceptionEnum.JDBC, SECONDARY_FIELD_NAME + ":" + secondaryId + "已存在映射");
        List<Integer> secondaryIds = new ArrayList<>(Collections.singletonList(secondaryId));
        addMappers(primaryId, secondaryIds, true);
    }

    //endregion

    //region######################################## edit #########################################

    public void editSecondaryIdOfPrimaryId(Integer primaryId, Integer secondaryId) {
        if (getPrimaryIdFromSecondaryId(secondaryId) != null && !getPrimaryIdFromSecondaryId(secondaryId).equals(primaryId))
            throw new AutoException(ExceptionEnum.JDBC, SECONDARY_FIELD_NAME + ":" + secondaryId + "已存在其他映射");
        editMappers(primaryId, new ArrayList<>(Collections.singletonList(secondaryId)), true);
    }

    public void editPrimaryIdOfSecondaryId(Integer secondaryId, Integer primaryId) {
        if (getSecondaryIdFromPrimaryId(primaryId) != null && !getSecondaryIdFromPrimaryId(primaryId).equals(secondaryId))
            throw new AutoException(ExceptionEnum.JDBC, PRIMARY_FIELD_NAME + ":" + primaryId + "已存在其他映射");
        editMappers(secondaryId, new ArrayList<>(Collections.singletonList(primaryId)), false);
    }

    //endregion

    //region######################################## delete ###########################################

    public void deleteSecondaryIdOfPrimaryId(Integer primaryId, Integer secondaryId) {
        List<Integer> secondaryIds = new ArrayList<>(Collections.singletonList(secondaryId));
        deleteMappers(primaryId, secondaryIds, true);
    }

    //endregion

}
